#include "../../Header/Game/fwStateManager.h"
#include "../../Header/fwLog.h"
#include "../../Header/Config/fwMacro.h"


StateManager * StateManager::m_pInstance = NULL;

StateManager::StateManager()
: m_pPrevState(NULL), m_pCurrState(NULL), m_pNextState(NULL)
{

}

StateManager::~StateManager()
{

}

StateManager * StateManager::GetInstance()
{
	if (!m_pInstance)
		m_pInstance = new StateManager();
	return m_pInstance;
}

void StateManager::DestroyInstance()
{
	SAFE_DEL(m_pInstance);
}

void StateManager::Destroy()
{
	int iSize = m_lstPrepState.size();
	for (int i = 0; i < iSize; i++)
	{
		State * temp = m_lstPrepState.at(i);
		temp->Destroy();
		SAFE_DEL(temp);
	}
	m_lstPrepState.clear();
}

void StateManager::Resize(int iSize)
{
	m_lstPrepState.resize(0);
}

void StateManager::RegisterState(State * pState)
{
	if (!pState)
	{
		LOGE("Can't reg null state");
		return;
	}

	//Search in list, if State is existed, it wouldn't be added into list
	int size = m_lstPrepState.size();
	for (int i = 0; i < size; i++)
	{
		if (m_lstPrepState.at(i))
		{
			if (strcmp(m_lstPrepState.at(i)->szName, pState->szName) == 0)
			{
				LOGW("State %s has already existed\n", pState->szName);
				return;
			}
		}
	}
	m_lstPrepState.push_back(pState);
}

void StateManager::Switch(State * pState)
{
	if (!pState)
	{
		LOGE("Can't switch to null state");
		return;
	}
	int iSize = m_lstPrepState.size();
	for (int i = 0; i < iSize; i++)
	{
		if (m_lstPrepState.at(i))
		{
			if (strcmp(m_lstPrepState.at(i)->szName, pState->szName) == 0)
			{
				if (m_lstPrepState.at(i) != pState)
				{
					SAFE_DEL(pState);
				}
				m_pNextState = m_lstPrepState.at(i);
				return;
			}
		}
	}

	m_lstPrepState.push_back(pState);
	m_pNextState = pState;
}

void StateManager::Switch(const char * szStateName)
{
	int iSize = m_lstPrepState.size();
	for (int i = 0; i < iSize; i++)
	{
		if (m_lstPrepState.at(i))
		{
			if (strcmp(m_lstPrepState.at(i)->szName, szStateName) != 0)
			{
				LOGE("There are not state %s\n", szStateName);
			}
			else
			{
				m_pNextState = m_lstPrepState.at(i);
			}
		}
	}
}

void StateManager::Swtich(const int iStateID)
{
	if ((unsigned int)iStateID >= m_lstPrepState.size())
	{
		LOGE("ID out of range\n");
		return;
	}

	State * temp = m_lstPrepState.at(iStateID);
	if (temp)
		m_pNextState = temp;
}

void StateManager::RemoveState(State * pState)
{
	if (!pState)
		return;
	int iSize = m_lstPrepState.size();
	for (int i = 0; i < iSize; i++)
	{
		if (m_lstPrepState.at(i) == pState)
		{
			SAFE_DEL(pState);
			return;
		}
	}
	LOGE("There are not state %s in list\n", pState->szName);
}

void StateManager::ExternalSwitch()
{
	if (m_pNextState)
	{
		if (m_pCurrState)
		{
			m_pPrevState = m_pCurrState;
			m_pCurrState->Destroy();
		}
		m_pCurrState = m_pNextState;
		m_pCurrState->Init();
		m_pNextState = NULL;
	}
}

State * StateManager::GetCurrentState()
{
	return m_pCurrState;
}